import sys
import fnmatch
from pathlib import Path

Import("env")  # type: ignore
env = env  # type: ignore
# 别管上面这行，留着就行

print(" ========== Script Start ======== ")

# 只用于C++ 编译器的参数
env.Append(
    CXXFLAGS=[
        "-Wno-volatile",
    ]
)

# ###################

# 查找并添加自定义库源文件
# 自定义源文件的定义是相对库文件夹得路径，比如ioxx/ioxx.c
# ioxx 是库文件夹名，ioxx.c 是要包含得源文件。
# 脚本将自动从几个库文件夹可能的位置中查找到具体的路径。
# 比如，ioxx 库可能位于lib 文件夹里，也可能在libdeps 里，
# 如果脚本在lib 中找到了库，就会把相对路径变成绝对路径 $PROJECT_DIR/lib/ioxx/ioxx.c,
# 然后将该源文件加入构建

extra_src = env.GetProjectOption("custom_lib_src")
extra_src = env.Split(extra_src)

lib_parent = env.subst('$LIBSOURCE_DIRS')
lib_parent = list(map(lambda x: Path(x), env.Split(lib_parent)))

if len(extra_src) > 0:
    print("Extra Sources Added From Lib:")

    for f in extra_src:
        print(f'\t{f}')
        fp = Path(f)
        lib_name = fp.parts[0]

        # 查找子文件夹
        src_path = None
        lib_path = None
        for l_p in lib_parent:
            if (l_p / lib_name).exists():
                lib_path = l_p / lib_name
                src_path = l_p / fp
                break

        assert (src_path is not None) and (lib_path is not None)
        # print('!> Lib: {lib_name}, not found, skip.')

        src_path = src_path.absolute()
        lib_path = lib_path.absolute()

        assert src_path.exists()
        # print('!> Lib src: {src_path.basename}, not found, skip.')

        variant = Path(f'$BUILD_DIR/extra/{lib_name}')

        if src_path != lib_path:
            rel_path = src_path.relative_to(lib_path)
            variant = variant / rel_path

        if src_path.is_dir():
            # 将文件夹加入构建
            env.BuildSources(str(variant), str(src_path))
        else:
            # 将单个文件加入构建，这部分用了没有文档的接口，
            # 功能是连蒙带猜的
            build_file = env.File(str(variant))

            middlewares = env.get("__PIO_BUILD_MIDDLEWARES")
            if middlewares:
                node = build_file
                new_node = build_file
                for callback, pattern in middlewares:
                    if pattern and not fnmatch.fnmatch(node.srcnode().get_path(), pattern):
                        continue
                    if callback.__code__.co_argcount == 2:
                        new_node = callback(env, new_node)
                    else:
                        new_node = callback(new_node)
                    if not new_node:
                        break
                if new_node:
                    build_file = new_node

            env.Append(PIOBUILDFILES=[env.Object(build_file)])
            env.VariantDir(str(variant.parent), str(src_path.parent))

print(" ========== Script Ended ======== ")

'''
pio = env.PioPlatform()

original_out = sys.stdout
f = open("d:/tttt.txt", "w")
sys.stdout = f

print('======= PIO =======')
print(dir(pio))

print('======= ENV =======')
print(type(env))
print(dir(env))


extra_src = env.GetProjectOption("custom_lib_src")
# print(type(extra_src))
# print(extra_src)


# for m in dir(env):
#     print(f'[[[  {m}  ]]]')
#     print(getattr(env, m))

# 所有环境变量
print('========= ENV._dict =========')
for k in env._dict:
    print(f'[[[  {k}  ]]]')
    print(env[k])


print('========= ENV FUNCTIONS =========')
# 环境函数
for m in dir(env):
    mm = getattr(env, m)
    if type(mm) == type(env.Replace):
        print(help(mm))

# 展开环境变量
print()
print(env.subst("$PROJECT_LIBDEPS_DIR\\$PIOENV"))

# 分割配置字符串
print()
print(env.Split(extra_src))

f.flush()
f.close()

sys.stdout = original_out


'''
